package groupb6.shopsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import groupb6.shopsystem.mapper.*;
import groupb6.shopsystem.pojo.entity.*;
import groupb6.shopsystem.pojo.form.AddCartForm;
import groupb6.shopsystem.pojo.form.AdmitOrderForm;
import groupb6.shopsystem.pojo.form.CustomerCartEditForm;
import groupb6.shopsystem.pojo.form.OrderIdForm;
import groupb6.shopsystem.pojo.res.ShoppingBagRes;
import groupb6.shopsystem.service.CustomerCartService;
import groupb6.shopsystem.service.CustomerProductService;
import groupb6.shopsystem.util.JWTUtil;
import groupb6.shopsystem.util.enums.OrderStatusEnum;
import groupb6.shopsystem.util.enums.ResponseEnum;
import groupb6.shopsystem.util.enums.IsReturnEnum;
import groupb6.shopsystem.util.response.ResponseException;
import groupb6.shopsystem.util.response.UniversalResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CustomerCartServiceImpl implements CustomerCartService {
    @Autowired
    private ShoppingBagMapper shoppingBagMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    private DestinationMapper destinationMapper;
    @Autowired
    private CustomerProductService customerProductService;

    @Override
    public UniversalResponse<List<ShoppingBagRes>> getShoppingBag() {
        Integer buyer_id = JWTUtil.getCurrentUser().getId();

        QueryWrapper<ShoppingBag> queryWrapperShoppingBag = new QueryWrapper<>();
        queryWrapperShoppingBag.eq("buyer_id", buyer_id);
        List<ShoppingBag> shoppingBagList = shoppingBagMapper.selectList(queryWrapperShoppingBag);
        if (shoppingBagList.isEmpty()) {
            return new UniversalResponse<>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg(), null);
        }

        Map<Integer, Integer> numberMap = shoppingBagList.stream().collect(Collectors.toMap(ShoppingBag::getProductId, ShoppingBag::getNumber));

        QueryWrapper<Product> queryWrapperProduct = new QueryWrapper<>();
        queryWrapperProduct.in("id", shoppingBagList.stream().map(ShoppingBag::getProductId).collect(Collectors.toList()));

        List<Product> productList = productMapper.selectList(queryWrapperProduct);
        List<ShoppingBagRes> resList = productList.stream().map((Product p) -> {
            ShoppingBagRes newRes = new ShoppingBagRes();
            newRes.setId(p.getId());
            newRes.setName(p.getName());
            newRes.setImagePath(p.getImagePath());
            newRes.setPrice(p.getPrice());
            newRes.setType(p.getType());
            newRes.setSold(p.getSold());
            newRes.setStock(p.getStock());
            newRes.setDetail(p.getDetail());
            newRes.setSellerId(p.getSellerId());
            newRes.setStatus(p.getStatus());
            newRes.setNumber(numberMap.get(p.getId()));

            return newRes;
        }).collect(Collectors.toList());

        return new UniversalResponse<>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg(), resList);
    }

    @Override
    @Transactional
    public UniversalResponse<?> admitOrder(List<AdmitOrderForm> admitOrderForm) {
        for (AdmitOrderForm admitOrderForm1 : admitOrderForm) {
            List<Product> checkList = orderMapper.check(admitOrderForm1.getProductId(), admitOrderForm1.getNumber());
            if (!checkList.isEmpty()) {
                return new UniversalResponse<>(5000, "following products sold out", checkList);
            }
        }

        List<Integer> productIdList = admitOrderForm.stream().map(AdmitOrderForm::getProductId).collect(Collectors.toList());
        //获得涉及到的商家列表
        List<Product> productList = productMapper.selectBatchIds(productIdList);
        //根据sellerId分组Product
        //<sellerId,List<Product>>
        Map<Integer, List<Product>> sellerProductMap = productList.stream()
                .collect(Collectors.groupingBy(Product::getSellerId));
        //<ProductId,form>
        Map<Integer, AdmitOrderForm> formMap = admitOrderForm.stream()
                .collect(Collectors.toMap(AdmitOrderForm::getProductId, Function.identity()));

        //根据组生成订单
        List<Order> newOrderList = new ArrayList<>();
        sellerProductMap.forEach((key, value) -> {

            //生成新的订单对象
            Order newOrder = new Order();
            newOrder.setStatus(OrderStatusEnum.PLACED.getStatus());
            newOrder.setStatusReturn(IsReturnEnum.NOT_RETURN.getIsReturn());
            float sumPrice = 0.0F;
            for (Product product : value) {
                sumPrice += formMap.get(product.getId()).getNumber() * product.getPrice();
            }
            newOrder.setPriceAll(sumPrice);
            newOrder.setSellerId(key);
            newOrder.setBuyerId(JWTUtil.getCurrentUser().getId());
            LambdaQueryWrapper<Destination> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Destination::getUserId, JWTUtil.getCurrentUser().getId())
                    .eq(Destination::getIsDefault, "1");
            List<Destination> destinations = destinationMapper.selectList(wrapper);
            LambdaQueryWrapper<Destination> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Destination::getUserId, key)
                    .eq(Destination::getIsDefault, "1");
            List<Destination> destinations1 = destinationMapper.selectList(wrapper1);
            if (destinations.isEmpty()) {
                throw new ResponseException(5000, "buyer does not have a default destination");
            }
            if (destinations1.isEmpty()) {
                throw new ResponseException(5000, "seller does not have a default destination");
            }
            newOrder.setDestinationIdBuyer(destinations.get(0).getId());
            newOrder.setDestinationIdSeller(destinations1.get(0).getId());
            newOrder.setOrderTime(new Timestamp(System.currentTimeMillis()));
            newOrderList.add(newOrder);
            //新订单入库
            orderMapper.insert(newOrder);
            //将订单关系添加到关系表
            for (Product product : value) {
                OrderProduct relation = new OrderProduct();
                relation.setProductId(product.getId());
                relation.setNumber(formMap.get(product.getId()).getNumber());
                relation.setOrderId(newOrder.getId());
                orderProductMapper.insert(relation);
            }
        });

        //将产品表中的库存数量减少
        for (Product product : productList) {
            product.setStock(product.getStock() - formMap.get(product.getId()).getNumber());
            productMapper.updateById(product);
        }

        //将购物车中对应的数据删除
        List<ShoppingBag> shoppingBagList = new ArrayList<>();
        for (Integer productId : productIdList) {
            ShoppingBag bag = new ShoppingBag();
            bag.setNumber(0);
            bag.setBuyerId(JWTUtil.getCurrentUser().getId());
            bag.setProductId(productId);
            shoppingBagList.add(bag);
        }
        editCart(CustomerCartEditForm.builder().shoppingBagList(shoppingBagList).build());
        return new UniversalResponse<>().ok(newOrderList);
    }

    @Override
    public UniversalResponse<?> payOrder(List<OrderIdForm> orderIdListForm) {
        User currentUser = JWTUtil.getCurrentUser();
        for (OrderIdForm orderIdForm : orderIdListForm) {
            Order currentOrder = orderMapper.selectById(orderIdForm.getOrderId());
            if (currentOrder.getBuyerId().equals(currentUser.getId())) {
                //订单属于买家
                if (currentOrder.getStatus().equals(OrderStatusEnum.PLACED.getStatus())) {
                    //订单状态正确
                    currentOrder.setStatus(OrderStatusEnum.PAID.getStatus());
                    orderMapper.updateById(currentOrder);
                } else {
                    //订单状态不正确
                    ResponseEnum res = ResponseEnum.ORDER_ERROR;
                    throw new ResponseException(res.getCode(), res.getMsg());
                }
            } else {
                //订单不是买家的
                ResponseEnum res = ResponseEnum.USER_NO_PERMISSION;
                throw new ResponseException(res.getCode(), res.getMsg());
            }
        }

        ResponseEnum res = ResponseEnum.SUCCESS;
        return new UniversalResponse<>(res.getCode(), res.getMsg());
    }

    @Override
    public void clearCart() {
        QueryWrapper<ShoppingBag> wrapper = new QueryWrapper<>();
        wrapper.eq("buyer_id", JWTUtil.getCurrentUser().getId());
        shoppingBagMapper.delete(wrapper);
    }

    @Override
    public void editCart(CustomerCartEditForm customerCartEditForm) {

        for (ShoppingBag shoppingBag : customerCartEditForm.getShoppingBagList()) {
            QueryWrapper<ShoppingBag> wrapper = new QueryWrapper<>();
            wrapper.eq("buyer_id", JWTUtil.getCurrentUser().getId())
                    .eq("product_id", shoppingBag.getProductId());
            try {
                shoppingBagMapper.update(shoppingBag, wrapper);
            } catch (Exception e) {
                log.warn("购物车中没找到对应物品");
            }

        }
        QueryWrapper<ShoppingBag> deletewrapper = new QueryWrapper<>();
        deletewrapper.eq("number", 0);
        shoppingBagMapper.delete(deletewrapper);
    }

    @Override
    @Transactional
    public void cancelOrder(Integer orderId) {
        Order order = orderMapper.selectById(orderId);
        //若订单已经支付或后续状态则无法取消
        if (!Objects.equals(order.getStatus(), OrderStatusEnum.PLACED.getStatus())) {
            throw new ResponseException(5000, "current order had been paid");
        }
        //删除关系
        LambdaQueryWrapper<OrderProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderProduct::getOrderId, orderId);
        List<OrderProduct> relationList = orderProductMapper.selectList(wrapper);
        orderProductMapper.delete(wrapper);
        //删除订单
        orderMapper.deleteById(orderId);
        List<Product> canceledProducts = new ArrayList<>();
        //将商品重新添加到商品表
        for (OrderProduct relation : relationList) {
            Product product = productMapper.selectById(relation.getProductId());
            product.setStock(product.getStock() + relation.getNumber());
            productMapper.updateById(product);
            canceledProducts.add(product);
        }
        //将商品重新添加到购物车
        AddCartForm addCartForm;
        for (OrderProduct relation : relationList) {
            addCartForm = new AddCartForm();
            addCartForm.setNumber(relation.getNumber());
            addCartForm.setProductId(relation.getProductId());
            customerProductService.addProIntoCart(addCartForm);
        }

    }
}
